/*
 *  Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.yinhai.localtx.starter;

import java.util.concurrent.*;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.yinhai.localtx.service.BusinessService;

/**
 * The type Dubbo business tester.
 */
public class DubboBusinessTester {
    /**
     * 设置线程池
     */
    private  static ThreadPoolExecutor poolExe = new ThreadPoolExecutor(100, 1000, 1, TimeUnit.HOURS,
            new LinkedBlockingDeque<Runnable>(100));
    /**
     * 并发数
     */
    private static final Integer CURRENT_NUM = 50;
    /**
     * 设置发令枪
     */
    private static CountDownLatch countDownLatch = new CountDownLatch(CURRENT_NUM);
    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(CURRENT_NUM+1);
    /**
     * The entry point of application.
     *
     * @param args the input arguments
     */
    public static void main(String[] args) {
        /**
         *  4. The whole e-commerce platform is ready , The buyer(U100001) create an order on the sku(C00321) , the count is 2
         */
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
            new String[]{"spring/dubbo-business.xml"});
        final BusinessService business = (BusinessService) context.getBean("business");
        for(int k =0;k<30;k++){
            beginCurrent(business);
        }
        
    
    
//        long start = System.currentTimeMillis();
//        for (int i = 0; i < CURRENT_NUM; i++) {
//            Runnable runnable = new Runnable(){
//                @Override
//                public void run() {
//                    try {
//                        System.out.println("线程" + Thread.currentThread().getName() + "等待执行");
//                        countDownLatch.await();
//                        System.out.println("线程" + Thread.currentThread().getName() + "开始执行");
//                        business.purchase("U100001", "C00321", 2);
//                        System.out.println("线程" + Thread.currentThread().getName() + "执行完成,进入屏障");
//                        cyclicBarrier.await();
//                    } catch (Exception e) {
//                        e.printStackTrace();
//                    }
//                }
//            };
//            poolExe.execute(runnable);
//            countDownLatch.countDown();
//            if(countDownLatch.getCount() == 0) {
//                System.out.println("所有线程已到位,开始计时 " + Thread.currentThread().getName());
//                 start = System.currentTimeMillis();
//            }
//        }
//        try {
//            cyclicBarrier.await(); // 等待所有的执行完成
//            System.out.println("所有线程都到达屏障,执行完成,进行计时");
//            long end = System.currentTimeMillis();
//            System.out.println("共计用时:"+(end-start));
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        poolExe.shutdown();
        
    }
    
    public static void beginCurrent(BusinessService business){
        long start = System.currentTimeMillis();
        for (int i = 0; i < CURRENT_NUM; i++) {
            Runnable runnable = new Runnable(){
                @Override
                public void run() {
                    try {
//                        System.out.println("线程" + Thread.currentThread().getName() + "等待执行");
                        countDownLatch.await();
//                        System.out.println("线程" + Thread.currentThread().getName() + "开始执行");
                        business.purchase("U100001", "C00321", 2);
//                        System.out.println("线程" + Thread.currentThread().getName() + "执行完成,进入屏障");
                        cyclicBarrier.await();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            poolExe.execute(runnable);
            countDownLatch.countDown();
            if(countDownLatch.getCount() == 0) {
//                System.out.println("所有线程已到位,开始计时 " + Thread.currentThread().getName());
                start = System.currentTimeMillis();
            }
        }
        try {
            cyclicBarrier.await(); // 等待所有的执行完成
//            System.out.println("所有线程都到达屏障,执行完成,进行计时");
            long end = System.currentTimeMillis();
            System.out.println((end-start));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
